/**@file
 * @brief Execute类实现
 * @see execute.h
 * @author 朱项男<libxiangnan@gmail.com>
 * @date 2011/11/30
 * @version 0.0.1
 * */

#include <list>

#include "execute.h"
#include "solution.h"
#include "suit.h"
#include "case.h"
#include "script.h"
#include "etTcl.h"

using namespace dat;
using namespace std;

//! @brief 构造函数
Execute::Execute() :
		etTcl(EtTcl()), signal(false) {
	;
}

//! @brief 析构函数
Execute::~Execute() {
	;
}

//! @brief 对象初始化行为
//! @note 该函数为保留函数，若无需初始化行为，该函数不做任何操作
void Execute::InitialExecution() {
	this->signal = false; //重置状态
	this->etTcl.CreateTclInterpreter();
	this->etTcl.configInterp();
}

//! @brief 测试对象Solution处理，执行测试任务
//! @param[in,out] sol Solution对象
void Execute::BeginExecute(dat::Solution &sol) {
	std::list<dat::Solution> innerSolutions = sol.getSolutions();
	std::list<dat::Suit> innerSuits = sol.getSuits();
	if(innerSolutions.empty() && innerSuits.empty()) {
		//	空Solution
		sol.setState(PASS);
		return;
	} else {
		/*	处理子Solution*/
		dat::EntityState solSta = NOT_RUN;
		if(!innerSolutions.empty()) {
			//	存在子Solutions
			std::list<dat::Solution>::iterator iter = innerSolutions.begin();
			for(; iter != innerSolutions.end(); ++iter) {
				if((*iter).getState() != DISABLED) {
					if(this->signal) break;	//	收到终止执行信号
					this->BeginExecute(*iter);
					if(solSta < (*iter).getState()) {
						solSta = (*iter).getState();
					}
				}
			}

			/*	更新子Solution列表*/
			sol.setSolutions(innerSolutions);
		} else {
			//	空子Solution列表
			solSta = PASS;
		}
		/*	处理子Suit*/
		dat::EntityState suiSta = NOT_RUN;
		if(!innerSuits.empty()) {
			//	存在子Suit
			std::list<Suit>::iterator iter = innerSuits.begin();
			for(; iter != innerSuits.end(); ++iter) {
				if((*iter).getState() != DISABLED) {
					if(this->signal) break;	//	收到终止执行信号
					this->BeginExecute(*iter);
					if(suiSta < (*iter).getState()) {
						suiSta = (*iter).getState();
					}
				}
			}

			/*	更新子Suit列表*/
			sol.setSuits(innerSuits);
		} else {
			suiSta = PASS;
		}

		/*	更新Solution状态*/
		dat::EntityState sta = NOT_RUN;
		if(NOT_RUN != suiSta || NOT_RUN != solSta) {
			sta = (suiSta <= solSta)? suiSta : solSta;
		}
		sol.setState(sta);
	}
}

//! @brief 测试对象Suit处理，执行测试任务
//! @param[in,out] sui Suit对象
void Execute::BeginExecute(dat::Suit &sui) {
	if(sui.getCases().empty()) {
		//Suit中不存在Case
		sui.setState(PASS);
	} else {
		std::list<dat::Case>innerCases = sui.getCases();
		std::list<dat::Case>::iterator iter = innerCases.begin();
		dat::EntityState sta = NOT_RUN;
		for(; iter != innerCases.end(); ++iter) {
			if((*iter).getState() != DISABLED) {
				if(this->signal) break;
				this->BeginExecute(*iter);
				if(sta < (*iter).getState()) {
					sta = (*iter).getState();
				}
			}
		}

		/*	更新Suit状态*/
		if(iter != innerCases.begin() && iter != innerCases.end()) {
			//	Suit执行部分时终止
			sui.setState(UNFINISH);
		} else {
			//	Suit未执行或全部执行
			sui.setState(sta);
		}

		/*	更新Suit中Cases列表*/
		sui.setCases(innerCases);
	}
}

//! @brief 测试对象Case处理，执行测试任务
//! @param[in,out] cas Case对象
void Execute::BeginExecute(dat::Case &cas) {
	if(cas.getScript().empty()) {
		//Case中不存在Script
		cas.setState(PASS);
	} else {
		std::list<dat::Script> innerScripts = cas.getScript();
		std::list<dat::Script>::iterator iter = innerScripts.begin();
		dat::EntityState sta = NOT_RUN;		//没有测试脚本执行
		for (; iter != innerScripts.end(); ++iter) {
			if ((*iter).getState() != DISABLED) {
				if(this->signal) break;		//用户停止执行时必须等到下一个可执行测试脚本前停止
				this->BeginExecute(*iter);
				if (sta < (*iter).getState()) {
					sta = (*iter).getState();
				}
			}
		}

		/*	更新Case状态*/
		if(iter != innerScripts.end() && iter != innerScripts.begin()) {
			//	Case执行且未执行完毕
			cas.setState(UNFINISH);
		} else {
			cas.setState(sta);
		}

		/*	更新Case中Script列表*/
		cas.setScripts(innerScripts);
	}
}
//! @brief 测试对象Script处理，执行测试任务
//! @param[in,out] scr Script对象
void Execute::BeginExecute(dat::Script &scr) {
	//this->etTcl.ExecuteScript(scr.getFulpath());
	scr.setState(PASS);
}

//! @brief 终止测试任务
void Execute::TerminateExecute() {
	this->signal = true;
}
//! @brief

